-- DPSCheck-Hunter.lua

local current_class, current_class_filename = UnitClass('player')
if current_class_filename ~= 'HUNTER' then
  return
end

------------------------------------------------------------
-- shared utility functions --------------------------------
------------------------------------------------------------

local get = DPSCheck_get
local get2 = DPSCheck_get2
local update_sum = DPSCheck_update_sum

------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------

-- avoid double counting clipping mistakes when kill shot available
local explosive_shot_clip_check = nil

------------------------------------------------------------
-- event matching ------------------------------------------
------------------------------------------------------------

local push_event_pattern = DPSCheck_push_event_pattern

push_event_pattern(function (current_state, combat_segment, input_event)
 	             if not explosive_shot_clip_check then
                       return
                     end

                     local spell_stats = combat_segment.statistics.priorities[input_event.spell_name]
                     if spell_stats == nil then
                       return
                     end

                     update_sum(spell_stats.mistakes, 'WAIT', 1)
                   end,
                   {event = 'COMBAT_LOG_EVENT_UNFILTERED', subevent = 'SPELL_AURA_REFRESH', source_flags = 1297, spell_name = 'Explosive Shot'})           

-- auto shot tracking

push_event_pattern(function (current_state, combat_segment, input_event)
                     update_sum(combat_segment.statistics, 'auto_shot_missed', 1)
                     update_sum(combat_segment.statistics, 'auto_shot_lost', 1)
                   end,
                   {event = 'COMBAT_LOG_EVENT_UNFILTERED', subevent = 'RANGE_MISSED', source_flags = 1297, miss_type = 'MISS'})

push_event_pattern(function (current_state, combat_segment, input_event)
                     update_sum(combat_segment.statistics, 'auto_shot_melee', 1)
                     update_sum(combat_segment.statistics, 'auto_shot_lost', 1)
                   end,
                   {event = 'COMBAT_LOG_EVENT_UNFILTERED', subevent = 'SWING_DAMAGE', source_flags = 1297})

push_event_pattern(function (current_state, combat_segment, input_event)
                     update_sum(combat_segment.statistics, 'auto_shot_melee_missed', 1)
                     update_sum(combat_segment.statistics, 'auto_shot_lost', 1)
                   end,
                   {event = 'COMBAT_LOG_EVENT_UNFILTERED', subevent = 'SWING_MISSED', source_flags = 1297, miss_type = 'MISS'})

push_event_pattern(function (current_state, combat_segment, input_event)
                     update_sum(combat_segment.statistics, 'auto_shot_failed', 1)
                     
		     local ranged_attack_speed = UnitRangedDamage('player')
                     if ranged_attack_speed ~= nil and ranged_attack_speed > 0 then
                       update_sum(combat_segment.statistics, 'auto_shot_lost', 0.5 / ranged_attack_speed)
                     end
                   end,
                   {event = 'UNIT_SPELLCAST_FAILED_QUIET', spell_name = 'Auto Shot', unit_id = 'player'})

push_event_pattern(function (current_state, combat_segment, input_event)
                     update_sum(combat_segment.statistics, 'auto_shot_succeeded', 1)
                   end,
                   {event = 'UNIT_SPELLCAST_SUCCEEDED', spell_name = 'Auto Shot', unit_id = 'player'})

push_event_pattern(function (current_state, combat_segment, input_event)
                     current_state.talents = input_event.talents
                   end,
                   {}, 
                   {'talents'})

------------------------------------------------------------
-- reporting functions -------------------------------------
------------------------------------------------------------

local class_checks_category = current_class .. ' Checks'

local push_priority_function = DPSCheck_push_priority_function

local function push_report_function(report_name, report_description, report_func)
  DPSCheck_push_report_function(report_name, class_checks_category, report_description, report_func)
end

push_report_function('auto shots', 
                     'Reports how many Auto Shots were fired versus an estimated maximum possible number of Auto Shots.',
                     function (combat_segment)
   		       -- missed are included in lost and succeeded already, so adjust below
                       local missed = get(combat_segment.statistics, 'auto_shot_missed', 0)

                       local succeeded = get(combat_segment.statistics, 'auto_shot_succeeded', 0) - missed
                       local lost = get(combat_segment.statistics, 'auto_shot_lost', 0)
                       local melee = get(combat_segment.statistics, 'auto_shot_melee', 0) + get(combat_segment.statistics, 'auto_shot_melee_missed', 0)
                       local failed = get(combat_segment.statistics, 'auto_shot_failed', 0)

                       local total = succeeded + lost
                       if total <= 0 then
                         return
                       end

                       if missed > 0 then
                         missed_comment = format('%d missed auto shots', missed)
                       end

                       if melee > 0 then
                         melee_comment = format('%d melee swings', melee)
                       end

                       if failed > 0 then
                         failed_comment = format('%d failed auto shots', failed)
                       end

                       comment = ''
                       if missed > 0 then
                         comment = missed_comment
                       end

                       if melee > 0 then
                         if comment == '' then
                           comment = melee_comment
                         else
                           comment = comment .. ', ' .. melee_comment
                         end
                       end

                       if failed > 0 then
                         if comment == '' then
                           comment = failed_comment
                         else
                           comment = comment .. ', ' .. failed_comment
                         end
                       end

                       return {succeeded, total, comment}
                     end)

local special_shot_checks = {}
special_shot_checks['Arcane Shot'] = 'spell_cast_success'
special_shot_checks['Aimed Shot'] = 'spell_cast_success'
special_shot_checks['Black Arrow'] = 'spell_cast_success'
special_shot_checks['Chimera Shot'] = 'spell_cast_success'
special_shot_checks['Explosive Shot'] = 'spell_cast_success'
special_shot_checks['Kill Shot'] = 'spell_cast_success'
special_shot_checks['Serpent Sting'] = 'spell_cast_success'
special_shot_checks['Steady Shot'] = 'spell_damage'

--push_report_function('gcd shot usage',
--                     'Reports number of special shots used per estimated GCD.',
--		     function (combat_segment)
-- 		       if combat_segment.statistics.active_time == nil then
--                         return
--                       end
--
--		       local special_shots = 0
-- 		       for k, v in pairs(special_shot_checks) do
--                         special_shots = special_shots + get2(combat_segment.statistics, v, k, 0)
--                       end
--
--                       local gcds = math.ceil(combat_segment.statistics.active_time / 1.5)
--                       if gcds < special_shots then
--                         gcds = special_shots
--                       end
--
--                       return {special_shots, gcds, ''}
--                     end)

local big_shot_priority = {'Chimera Shot', 'Kill Shot', 'Explosive Shot'}--, 'Aimed Shot'}
local function check_shot_priority(current_spell_name, available_spell_names)
  if current_spell == 'Chimera Shot' then
    -- TODO : check for serpent sting on target. be smart about almost dead targets.
  elseif current_spell == 'Explosive Shot' then
    -- TODO : check for explosive shot DOT
  end

  for i, spell_name in ipairs(big_shot_priority) do
    if current_spell_name == spell_name then
      -- no higher priority spells available
      return
    end

    if available_spell_names[spell_name] then
      return spell_name
    end
  end
end

push_priority_function('Readiness',
                       'Readiness resets all cooldowns, so Rapid Fire should always be used beforehand. (Rapid Fire is off the GCD.)',
               	       function (current_spell_name, available_spell_names)
                         if available_spell_names['Rapid Fire'] ~= nil then
                           return 'Rapid Fire'
                         end

                         return
                       end)

--push_priority_function('Chimera Shot',
--                       'Chimera Shot is only delayed to apply Serpent Sting to a target. The current implementation does not check whether Serpent Sting is on the target.',
--                       check_shot_priority)

--push_priority_function('Kill Shot',
--                       'Kill Shot is preferred over all shots except Chimera Shot (MM only).',
--                       check_shot_priority)

--push_priority_function('Explosive Shot',
--                       'Explosive Shot is preferred over all shots except Kill Shot and waiting for the Explosive Shot debuff to fall off.',
--               	       function (current_spell_name, available_spell_names)
--                         if available_spell_names['Kill Shot'] ~= nil then
--                           explosive_shot_clip_check = nil
--                           return 'Kill Shot'
--                         end
--
--                         explosive_shot_clip_check = true                           
--                       end)

--push_priority_function('Aimed Shot',
--                       'Aimed Shot has lower priority than Chimera Shot, Kill Shot, and Explosive Shot.',
--                       check_shot_priority)

push_priority_function('Arcane Shot',
                       'Arcane Shot has lower priority than Chimera, Kill Shot, Explosive Shot.',
                       check_shot_priority)

--push_priority_function('Steady Shot', 
--		       'Steady Shot is generally not used when other special shots are available. The main exception is Arcane Shot which may do less damage with high levels of armor penetration',
--                       check_shot_priority)
